#########################################################################
# Figure2_a.R
# Will be used in Figure2.R
#########################################################################

#########################################################################
# 1. Process Data
#########################################################################

dt <- read.csv("qualtrics_Oakland.csv")[-c(1:2), ] %>%
  rename(
    C1_9 = C1_17, C1_10 = C1_18,
    C2_9 = C2_17, C2_10 = C2_18
  ) %>%
  mutate(id = row_number())


# Set a reference order

ref_set <- c(
  "Scott", "Hodge", "Taylor",
  "Liu", "Thao", "Fuente",
  "Villanueva", "Reimann", "Jordan",
  "Reid"
)

#########################################################################
# 2. Average Ranks
#########################################################################

# Decompose ballot position x candidate

dtc <- dt %>%
  separate(C2_DO,
    into = c(
      "C2_pos1", "C2_pos2", "C2_pos3",
      "C2_pos4", "C2_pos5", "C2_pos6",
      "C2_pos7", "C2_pos8", "C2_pos9",
      "C2_pos10"
    ),
    sep = "[|]", remove = F
  ) %>% # Separate by "|"
  dplyr::select(id, starts_with("C2"), -c("C2_DO")) %>%
  pivot_longer(
    cols = C2_1:C2_10,
    values_to = "rank"
  ) %>%
  dplyr::select(id, name, rank, everything()) %>%
  mutate(
    name = case_when(
      name == "C2_1" ~ ref_set[1],
      name == "C2_2" ~ ref_set[2],
      name == "C2_3" ~ ref_set[3],
      name == "C2_4" ~ ref_set[4],
      name == "C2_5" ~ ref_set[5],
      name == "C2_6" ~ ref_set[6],
      name == "C2_7" ~ ref_set[7],
      name == "C2_8" ~ ref_set[8],
      name == "C2_9" ~ ref_set[9],
      name == "C2_10" ~ ref_set[10]
    ),
    rank = as.numeric(rank)
  )


g_list <- list()
treat_vec <- c(
  "1st", "2nd", "3rd", "4th", "5th",
  "6th", "7th", "8th", "9th", "10th"
)


for (j in 1:10) { # For all candidates j = 1,...,10

  # Extracting only one candidate
  temp <- dtc %>%
    filter(name == ref_set[j])

  est <- NA
  upp <- NA
  low <- NA
  treat_name <- NA

  for (t in 1:10) { # For all positions t = 1,...,10s

    treated_pos <- paste0("C2_pos", t)
    treated_pos_v <- temp[treated_pos] %>% pull()

    temp_t <- temp %>%
      mutate(treated = ifelse(grepl(ref_set[1], treated_pos_v),
        1, # Candidate j is in position t (treated)
        0
      )) %>% # Otherwise (control)
      dplyr::select(id, name, rank, treated, everything())


    m <- lm(rank ~ treated, temp_t) # Computing ballot order effect
    est[t] <- summary(m)$coefficients[2, 1]
    upp[t] <- confint(m, level = 0.95)[2, 2] # 97.5%
    low[t] <- confint(m, level = 0.95)[2, 1] # 2.5%
    treat_name[t] <- treat_vec[t]
  }


  g_list[[j]] <- t(rbind(est, upp, low)) %>%
    as_tibble() %>%
    mutate(
      cand = ref_set[j],
      ps = "Average Rank Effects",
      treatment = treat_name
    ) %>%
    data.frame()
}


g_list

g_out <- as.data.frame(do.call(rbind, g_list))
g_out$treatment <- factor(g_out$treatment, levels = treat_vec)
g_out$col <- ifelse(g_out$low > 0, "A", "C")
g_out$col <- ifelse(g_out$upp < 0, "B", g_out$col)
g_out$cand <- factor(g_out$cand, levels = rev(sort(unique(g_out$cand))))

set.seed(42)
p <- ggplot(g_out, aes(x = cand, y = est)) +
  geom_hline(yintercept = 0, colour = "black", lty = 2, lwd = 0.5) +
  geom_point(aes(x = cand, y = est, color = col)) +
  geom_linerange(aes(x = cand, ymin = low, ymax = upp, color = col), lwd = 0.5) +
  facet_grid(cols = vars(treatment)) +
  scale_colour_manual(values = c("#b0015a", "#128ba0", "gray")) +
  theme_classic() +
  scale_y_reverse(limits = c(-3, 3)) +
  ylab("") +
  xlab("") +
  ggtitle("Oakland Mayoral (Average Ranks)") +
  theme(
    legend.position = "none", plot.margin = margin(0.2, 0.2, 0.2, -0.2, "cm"),
    strip.text.x = element_text(color = "dimgray", size = 7), text = element_text(size = 8)
  ) +
  scale_y_continuous(guide = guide_axis(angle = 90)) +
  coord_flip()
p


#########################################################################
# 3. Candidate Selection
#########################################################################

# Decompose ballot position x candidate

dtc <- dt %>%
  separate(C1_DO,
    into = c(
      "C1_pos1", "C1_pos2", "C1_pos3",
      "C1_pos4", "C1_pos5", "C1_pos6",
      "C1_pos7", "C1_pos8", "C1_pos9",
      "C1_pos10"
    ),
    sep = "[|]", remove = F
  ) %>% # Separate by "|"
  dplyr::select(id, starts_with("C1"), -c("C1_DO")) %>%
  pivot_longer(
    cols = C1_1:C1_10,
    values_to = "rank"
  ) %>%
  mutate(
    name = case_when(
      name == "C1_1" ~ ref_set[1],
      name == "C1_2" ~ ref_set[2],
      name == "C1_3" ~ ref_set[3],
      name == "C1_4" ~ ref_set[4],
      name == "C1_5" ~ ref_set[5],
      name == "C1_6" ~ ref_set[6],
      name == "C1_7" ~ ref_set[7],
      name == "C1_8" ~ ref_set[8],
      name == "C1_9" ~ ref_set[9],
      name == "C1_10" ~ ref_set[10]
    ),
    rank = as.numeric(rank),
    selection = ifelse(is.na(rank), 0, 1)
  ) %>%
  dplyr::select(id, name, selection, rank, everything())


g_list <- list()
treat_vec <- c(
  "1st", "2nd", "3rd", "4th", "5th",
  "6th", "7th", "8th", "9th", "10th"
)


for (j in 1:10) { # For all candidates j = 1,...,10

  # Extracting only one candidate
  temp <- dtc %>%
    filter(name == ref_set[j])

  est <- NA
  upp <- NA
  low <- NA
  treat_name <- NA

  for (t in 1:10) { # For all positions t = 1,...,10s

    treated_pos <- paste0("C1_pos", t)
    treated_pos_v <- temp[treated_pos] %>% pull()

    temp_t <- temp %>%
      mutate(treated = ifelse(grepl(ref_set[1], treated_pos_v),
        1, # Candidate j is in position t (treated)
        0
      )) %>% # Otherwise (control)
      dplyr::select(id, name, rank, treated, everything())


    m <- lm(selection ~ treated, temp_t) # Computing ballot order effect
    est[t] <- summary(m)$coefficients[2, 1]
    upp[t] <- confint(m, level = 0.95)[2, 2] # 97.5%
    low[t] <- confint(m, level = 0.95)[2, 1] # 2.5%
    treat_name[t] <- treat_vec[t]
  }


  g_list[[j]] <- t(rbind(est, upp, low)) %>%
    as_tibble() %>%
    mutate(
      cand = ref_set[j],
      ps = "Average Rank Effects",
      treatment = treat_name
    ) %>%
    data.frame()
}


g_list

g_out <- as.data.frame(do.call(rbind, g_list))
g_out$treatment <- factor(g_out$treatment, levels = treat_vec)
g_out$col <- ifelse(g_out$low > 0, "A", "C")
g_out$col <- ifelse(g_out$upp < 0, "B", g_out$col)
g_out$cand <- factor(g_out$cand, levels = rev(sort(unique(g_out$cand))))

p2 <- ggplot(g_out, aes(x = cand, y = est)) +
  geom_hline(yintercept = 0, colour = "black", lty = 2, lwd = 0.5) +
  geom_point(aes(x = cand, y = est, color = col)) +
  geom_linerange(aes(x = cand, ymin = low, ymax = upp, color = col), lwd = 0.5) +
  facet_grid(cols = vars(treatment)) +
  scale_colour_manual(values = c("#128ba0", "#b0015a", "gray")) +
  theme_classic() +
  expand_limits(y = c(-0.5, 0.5)) +
  ylim(-0.5, 0.5) +
  ylab("") +
  xlab("") +
  ggtitle("Oakland Mayoral (Candidate Selection)") +
  theme(
    legend.position = "none", plot.margin = margin(0.2, 0.2, 0.2, -0.2, "cm"),
    strip.text.x = element_text(color = "dimgray", size = 7), text = element_text(size = 8)
  ) +
  scale_y_continuous(guide = guide_axis(angle = 90)) +
  coord_flip()

p2


#########################################################################
# 4. Combine All Panels
#########################################################################

p_oakland <- ggarrange(p, p2, ncol = 1)
